home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Calculators / Calculette / Source / Calculette.m < prev    next >
Text File  |  1994-02-28  |  10KB  |  531 lines

  1. #import "Calculette.h"
  2. #import "Printer.h"
  3. #import "Info.h"
  4.  
  5. @implementation Calculette
  6.  
  7. + initialize
  8. {
  9.   static NXDefaultsVector CalculetteDefaults = {
  10.     "Printed",        "0",
  11.     "Fixed",        "0",
  12.     "Precision",    "2",
  13.     0,            0,
  14.   };
  15.  
  16.   NXRegisterDefaults( "Calculette", CalculetteDefaults );
  17.  
  18.   return self;
  19. }
  20.  
  21. - display
  22. {
  23.   char s[ 64 ];
  24.  
  25.   if ( fixed )
  26.     sprintf( s, "%.*f", precision, display );
  27.   else
  28.     sprintf( s, "%.10g", display );
  29.  
  30.   [ text setStringValue:s ];
  31.  
  32.   if ( memory )     /* redisplay memory indicator on top */
  33.     [ memoryIndicator display ];
  34.  
  35.   return self;
  36. }
  37.  
  38. - clear:sender
  39. {
  40.   if ( display == 0.0 ) {
  41.     value = 0.0;
  42.     entered = NO;
  43.   }
  44.  
  45.   input = display = 0.0;
  46.   decimals = 0;
  47.  
  48.   [ self display ];
  49.  
  50.   return self;
  51. }
  52.  
  53. - digit:(int)n
  54. {
  55.   if ( entered ) {
  56.     entered = NO;
  57.     decimals = 0;
  58.     display = 0.0;
  59.   }
  60.  
  61.   if ( decimals )
  62.     display = display + ( n / pow( 10, decimals++ ));
  63.   else
  64.     display = display * 10 + n;
  65.  
  66.   [ self display ];
  67.  
  68.   return self;
  69. }
  70.  
  71. - point:sender
  72. {
  73.   if ( entered ) {
  74.     entered = NO;
  75.     decimals = 1;
  76.     display = 0.0;
  77.   }
  78.   else {
  79.     if ( decimals )
  80.       NXBeep( );
  81.     else
  82.       decimals = 1;
  83.   }
  84.  
  85.   [ self display ];
  86.  
  87.   return self;
  88. }
  89.  
  90. - operation:(int)op
  91. {
  92.   if ( !entered ) {
  93.     input = display;
  94.     entered = YES;
  95.   }
  96.  
  97.   switch( op ) {
  98.   case '+' :
  99.     value += input;
  100.     break;
  101.   case '-':
  102.     value -= input;
  103.     break;
  104.   case '*':
  105.     value *= input;
  106.     break;
  107.   case '/':
  108.     if ( input == 0.0 )
  109.       NXBeep( );
  110.     else
  111.       value /= input;
  112.     break;
  113.   case '=' :
  114.     break;
  115.   default:
  116.     break;
  117.   }
  118.  
  119.   display = value;
  120.  
  121.   [ self display ];
  122.  
  123.   if ( printed ) {
  124.     char s[ 64 ];
  125.  
  126.     if ( fixed )
  127.       sprintf( s, "%c\t%.*f\n", op, precision, op == '=' ? value : input );
  128.     else
  129.       sprintf( s, "%c\t%.10g\n", op, op == '=' ? value : input );
  130.  
  131.     [ printer appendToText:s ];
  132.   }
  133.  
  134.   return self;
  135. }
  136.  
  137. - percent:sender
  138. {
  139.   if ( !entered ) {
  140.     input = display;
  141.     entered = YES;
  142.   }
  143.  
  144.   display = value * input / 100.0;
  145.  
  146.   [ self display ];
  147.  
  148.   input = display;
  149.  
  150.   return self;
  151. }
  152.  
  153. - zero:sender        { return [ self digit:0 ]; }
  154. - one:sender        { return [ self digit:1 ]; }
  155. - two:sender        { return [ self digit:2 ]; }
  156. - three:sender        { return [ self digit:3 ]; }
  157. - four:sender        { return [ self digit:4 ]; }
  158. - five:sender        { return [ self digit:5 ]; }
  159. - six:sender        { return [ self digit:6 ]; }
  160. - seven:sender        { return [ self digit:7 ]; }
  161. - eight:sender        { return [ self digit:8 ]; }
  162. - nine:sender        { return [ self digit:9 ]; }
  163.  
  164. - plus:sender        { return [ self operation:'+' ]; }
  165. - minus:sender        { return [ self operation:'-' ]; }
  166. - multiply:sender    { return [ self operation:'*' ]; }
  167. - divide:sender        { return [ self operation:'/' ]; }
  168.  
  169. - equal:sender        { return [ self operation:'=' ]; }
  170.  
  171. - memoryRecall:sender;
  172. {
  173.   input = display = memory;
  174.   entered = YES;
  175.  
  176.   [ self display ];
  177.  
  178.   return self;
  179. }
  180.  
  181. - memoryClear:sender
  182. {
  183.   memory = 0.0;
  184.  
  185.   [ memoryIndicator setStringValueNoCopy:0 ];
  186.  
  187.   return self;
  188. }
  189.  
  190. - memoryPlus:sender;
  191. {
  192.   memory += display;
  193.  
  194.   [ memoryIndicator setStringValueNoCopy:memory ? "M" : 0  ];
  195.  
  196.   return self;
  197. }
  198.  
  199. - memoryMinus:sender;
  200. {
  201.   memory -= display;
  202.  
  203.   [ memoryIndicator setStringValueNoCopy:memory ? "M" : 0  ];
  204.  
  205.   return self;
  206. }
  207.  
  208. - fix:sender
  209. {
  210.   fixed = fixed ? NO : YES;
  211.  
  212.   [ self display ];
  213.  
  214.   return self;
  215. }
  216.  
  217. - precision:sender
  218. {
  219.   precision = [[ sender selectedCell ] tag ];
  220.  
  221.   [ self display ];
  222.  
  223.   return self;
  224. }
  225.  
  226. - showInfoPanel:sender
  227. {
  228.   if ( !infoPanel ) 
  229.     if ( ![ NXApp loadNibSection:"Info.nib" owner:self ] )
  230.       return nil;
  231.  
  232.   if ( ![ infoPanel isVisible ] )
  233.     [ infoPanel center ];
  234.  
  235.   [ infoPanel makeKeyAndOrderFront:nil ];
  236.  
  237.   [ infoView animateInfo:self ];
  238.   
  239.   return self;
  240. }
  241.  
  242. - (BOOL)menuActive:menuCell
  243. {
  244.   BOOL    shouldBeEnabled = printer ? YES : NO;
  245.  
  246.   if ( [ menuCell isEnabled ] != shouldBeEnabled ) {
  247.     [ menuCell setEnabled:shouldBeEnabled ];
  248.     return YES;
  249.   }
  250.   return NO;
  251. }
  252.  
  253. - (BOOL)revertToSavedMenuActive:menuCell
  254. {
  255.   BOOL    shouldBeEnabled = (printer ? YES : NO)
  256.     && [[ printer window ] isDocEdited ]
  257.       && [ printer file ];
  258.  
  259.   if ( [ menuCell isEnabled ] != shouldBeEnabled ) {
  260.     [ menuCell setEnabled:shouldBeEnabled ];
  261.     return YES;
  262.   }
  263.   return NO;
  264. }
  265.  
  266. - showPrefPanel:sender
  267. {
  268.   NXRect calcFrame;
  269.   NXCoord x, y;
  270.  
  271.   if ( !prefPanel ) 
  272.     if ( ![ NXApp loadNibSection:"Preferences.nib" owner:self ] )
  273.       return nil;
  274.  
  275.   [ window getFrame:&calcFrame ];
  276.  
  277.   x = NX_X( &calcFrame ) + 39;
  278.   y = NX_Y( &calcFrame ) + 22;
  279.  
  280.   [ prefPanel moveTo:x :y ];
  281.   [ prefPanel makeKeyAndOrderFront:nil ];
  282.  
  283.   return self;
  284. }
  285.  
  286. - newPrinter:sender
  287. {
  288.   NXRect baseFrame;
  289.   NXCoord x, y;
  290.  
  291.   if ( ![ NXApp loadNibSection:"Printer.nib" owner:self ] )
  292.     return nil;
  293.  
  294.   [[ printer text ] setDelegate:[[ printer window ] delegate ]]; // IB (3.1) could not do it
  295.   [[ printer text ] setSel:0 :0 ];
  296.  
  297.   if ( listOfPrinters == 0 )
  298.     listOfPrinters = [[ List alloc ] init ];
  299.  
  300.   if ( [ listOfPrinters count ] ) {
  301.     [[[ listOfPrinters lastObject ] window ] getFrame:&baseFrame ];
  302.  
  303.     x = NX_X( &baseFrame ) + 22;
  304.     y = NX_Y( &baseFrame ) - 24;
  305.   }
  306.   else {
  307.     [ window getFrame:&baseFrame ];
  308.  
  309.     x = NX_X( &baseFrame ) + NX_WIDTH( &baseFrame ) - 1;
  310.     y = NX_Y( &baseFrame );
  311.   }
  312.  
  313.   [[ printer window ] moveTo:x :y ];
  314.   [[ printer window ] makeKeyAndOrderFront:nil ];
  315.  
  316.   [ listOfPrinters addObject:printer ];
  317.  
  318.   return self;
  319. }
  320.  
  321. - openPrinter:sender
  322. {
  323.   char *types[ 2 ] = { "calculette", 0 };
  324.   OpenPanel *openPanel = [ OpenPanel new ];
  325.   
  326.   if ( [ openPanel runModalForTypes:types ] )
  327.     if ( [ self newPrinter:self ] )
  328.       [ printer load:[ openPanel filename ] ];
  329.  
  330.   return self;
  331. }
  332.  
  333. - copy:sender
  334. {
  335.   Pasteboard *pboard;
  336.   NXAtom types[ 1 ];
  337.  
  338.   const char *s = [ text stringValue ];
  339.  
  340.   types[ 0 ] = NXAsciiPboardType;
  341.  
  342.   pboard = [ Pasteboard new ];
  343.   [ pboard declareTypes:types num:2 owner:0 ];
  344.   [ pboard writeType:NXAsciiPboardType data:s length:strlen( s ) ];
  345.  
  346.   return self;
  347. }
  348.  
  349. - paste:sender
  350. {
  351.   Pasteboard *pboard;
  352.   NXAtom types[ 1 ];
  353.  
  354.   const char *data;
  355.   int length;
  356.  
  357.   double dval;
  358.  
  359.   types[ 0 ] = NXAsciiPboardType;
  360.   
  361.   pboard = [ Pasteboard new ];
  362.  
  363.   if ( [ pboard findAvailableTypeFrom:types num:1 ] )
  364.     if ( [ pboard readType:NXAsciiPboardType data:&data length:&length ] )
  365.       if ( sscanf( data, "%lf", &dval ) == 1 ) {
  366.     input = display = dval;    // just like a memory recall
  367.     entered = YES;
  368.  
  369.     [ self display ];
  370.  
  371.     return self;
  372.       }
  373.  
  374.   NXBeep( );
  375.  
  376.   return nil;
  377. }
  378.  
  379. - cut:sender
  380. {
  381.   [[ self copy:sender ] clear:sender ];
  382.  
  383.   return self;
  384. }
  385.  
  386. - print:sender
  387. {
  388.   printed = printed ? NO : YES;
  389.  
  390.   if ( printed ) {
  391.     if ( !printer ) {
  392.       [ self newPrinter:self ];
  393.       [[ printer text ] setSel:0 :0 ];
  394.     }
  395.     else
  396.       [[ printer window ] orderFront:sender ];
  397.   }
  398.  
  399.   return self;
  400. }
  401.  
  402. - removePrinter:sender
  403. {
  404.   if ( sender == printer ) {
  405.     printed = NO;
  406.     printer = nil;
  407.     [ printerButton setState:printed ];
  408.   }
  409.  
  410.   [ listOfPrinters removeObject:sender ];
  411.  
  412.   return self;
  413. }
  414.  
  415. - changePrinter:sender
  416. {
  417.   printer = sender;
  418.  
  419.   return self;
  420. }
  421.  
  422. @end
  423.  
  424. @implementation Calculette( WindowDelegate )
  425.  
  426. - windowDidMove:sender
  427. {
  428.   [ window saveFrameUsingName:"Calculette" ];
  429.  
  430.   return self;
  431. }
  432.  
  433. @end
  434.  
  435. @implementation Calculette( ApplicationDelegate )
  436.  
  437. - appDidInit:sender
  438. {
  439.   NXImage *miniwindowImage = [[ NXImage alloc ] initFromSection:"PrinterM.tiff" ];
  440.  
  441.   printed = strcmp( NXGetDefaultValue( "Calculette", "Printed" ), "1" ) == 0 ? YES : NO;
  442.   [ printerButton setState:printed ];
  443.  
  444.   fixed = strcmp( NXGetDefaultValue( "Calculette", "Fixed" ), "1" ) == 0 ? YES : NO;
  445.   [ fixButton setState:fixed ];
  446.  
  447.   precision = atoi( NXGetDefaultValue( "Calculette", "Precision" ));
  448.   [[ precisionPopUpList itemList ] selectCellWithTag:precision ];
  449.   [ precisionPopUpButton setTitle:[[[ precisionPopUpList itemList ] selectedCell ] title ]];
  450.  
  451.   [ self display ]; // format the display register according to preferences
  452.  
  453.   [ window setFrameUsingName:"Calculette" ];
  454.   [ window makeKeyAndOrderFront:nil ];
  455.  
  456.   if ( [ listOfPrinters count ] ) { /* launched by Workspace */
  457.     NXRect baseFrame;
  458.     NXCoord x, y;
  459.  
  460.     [ window getFrame:&baseFrame ];
  461.  
  462.     x = NX_X( &baseFrame ) + NX_WIDTH( &baseFrame ) - 1;
  463.     y = NX_Y( &baseFrame );
  464.  
  465.     [[ printer window ] moveTo:x :y ];
  466.   }
  467.  
  468.   if ( miniwindowImage )
  469.     [ miniwindowImage setName:"Miniprinter" ];
  470.  
  471.   [ saveMenuCell setUpdateAction:@selector( menuActive: ) forMenu:printerMenu ];
  472.   [ saveAsMenuCell setUpdateAction:@selector( menuActive: ) forMenu:printerMenu ];
  473.   [ revertToSavedMenuCell setUpdateAction:@selector( revertToSavedMenuActive: ) forMenu:printerMenu ];
  474.   [ pageLayoutMenuCell setUpdateAction:@selector( menuActive: ) forMenu:formatMenu ];
  475.   [ printMenuCell setUpdateAction:@selector( menuActive: ) forMenu:[NXApp mainMenu ]];
  476.  
  477.   [ NXApp setAutoupdate:YES ];
  478.  
  479.   if ( printed )
  480.     [ self newPrinter:self ];
  481.  
  482.   return self;
  483. }
  484.  
  485. - (BOOL)appAcceptsAnotherFile:sender
  486. {
  487.   return YES;
  488. }
  489.  
  490. - (int)app:sender openFile:(const char *)aFile type:(const char *)aType
  491. {
  492.   if ( [ self newPrinter:self ] )
  493.     if ( [ printer load:aFile ] )
  494.       return YES;
  495.  
  496.   return NO;
  497. }
  498.  
  499. - appWillTerminate:sender
  500. {
  501.   int i;
  502.   id winList = [ NXApp windowList ];
  503.  
  504.   for ( i = 0; i < [ winList count ]; i++ ) {
  505.     id win = [ winList objectAt:i ];
  506.  
  507.     if ( [[ win delegate ] isKindOf:[ Printer class ]] && [ win isDocEdited ] ) {
  508.       switch ( NXRunAlertPanel( "Quit", "There are edited windows.", "Review Unsaved", "Quit Anyway", "Cancel" )) {
  509.       case NX_ALERTDEFAULT:
  510.     do {
  511.       id win = [ winList objectAt:i ];
  512.       if ( [[ win delegate ] isKindOf:[ Printer class ]] )
  513.         [ win performClose:nil ];
  514.     } while ( ++i < [ winList count ] );
  515.  
  516.     return self;
  517.  
  518.       case NX_ALERTALTERNATE:
  519.     return self;
  520.  
  521.       case NX_ALERTOTHER:
  522.       default:
  523.     return nil;
  524.       }
  525.     }
  526.   }
  527.   return self;
  528. }
  529.  
  530. @end
  531.